//#define _XOPEN_SOURCE  1
//#define _SVID_SOURCE  1
//#define _POSIX_SOURCE  1
#define _BSD_SOURCE  1
#include <header.h>

/*
在今天代码的基础上: 实现函数(客户端): 
该函数可以在不使用MSG_WAITALL的情况下，往buf指向的内存中接收任意长度(length)的数据。
即: 把我们的代码由 recv(netFd,buf, len,MSG_WAITALL)  改为调用我们自己实现的 recvn(netfd, buf, length)
*/
int recvn(int netfd, void *buf, int length){
	ssize_t recived = 0;
	while (recived == length){
		ssize_t byte = recv(netfd, buf, length - recived, 0);
		recived += byte;
	}
	return 0;
}

/* 此版本为传输大文件 */
int main(int argc, char* argv[]){
	ARGS_CHECK(argc, 1);

	char *ip = "192.168.169.128";
	char *port = "8080";

	int net_fd = socket(AF_INET, SOCK_STREAM, 0);

	struct sockaddr_in client_addr;
	client_addr.sin_family = AF_INET;
	client_addr.sin_port = htons(atoi(port));
	client_addr.sin_addr.s_addr = inet_addr(ip);

	connect(net_fd, (struct sockaddr*)&client_addr, sizeof(client_addr));
	
    
    
    off_t file_size;
	recv(net_fd, &file_size, sizeof(off_t), MSG_WAITALL);
    printf("文件大小:%ld\n", file_size);

	// 先传文件名的长度，再传文件名
	int name_len = 0;
	recv(net_fd, &name_len, sizeof(int), MSG_WAITALL);
	
    char fileName[60] = {0};
    recv(net_fd, fileName, name_len, MSG_WAITALL);
    printf("fileName: %s \n", fileName);

    int file_fd = open(fileName, O_RDWR | O_CREAT, 0600);

    // mmap
    ftruncate(file_fd, file_size);
    void *p = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, file_fd, 0);
	recvn(net_fd, p, file_size);
    munmap(p, file_size);


	close(file_fd);
	close(net_fd);
	return 0;
}